package com.xlh.virtualization.websocket;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.gson.Gson;
import com.xlh.dao.courseTest.helper.ExperimentVideoStatisticsMapperHelper;
import com.xlh.param.courseTest.ExperimentStatisticsParamOther;
import com.xlh.pojo.courseTest.ExperimentVideoStatistics;
import com.xlh.service.courseTest.ExperimentService;
import com.xlh.util.SpringContextUtil;
import com.xlh.websocket.GetHttpSessionConfigurator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 课程实验WebSocket，用于记录实验视频时长和停止容器
 *
 * @author cheer
 */
@ServerEndpoint(value = "/ws/experiment/course/videotime/{chapterId}", configurator = GetHttpSessionConfigurator.class)
@Component
@Slf4j
public class CourseExperimentVideoTimeWebsocket {


    private static final ExperimentVideoStatisticsMapperHelper experimentHelper = SpringContextUtil.getBean(ExperimentVideoStatisticsMapperHelper.class);

    private static final ExperimentService experimentService = SpringContextUtil.getBean(ExperimentService.class);
    /**
     * 存储连接 userId , taskId, websocketList
     */
    private static Table<Long, Long, List<CourseExperimentVideoTimeWebsocket>> connectionMap = HashBasedTable.create();

    /**
     * 存储计时 userId, taskId, date
     */


    Table<Long, Long, Object> TimeHashMap = HashBasedTable.create();

    private Session session;

    /**
     * 用户Id
     */
    private Long userId;

    /**
     * 章节Id
     */
    private Long chapterId;
    /**
     * 课程Id
     */
    private Long courseId;
    /**
     * 班级Id
     */
    private Long classId;
    /**
     * 任务Id
     */
    private Long taskId;
    /**
     * 步骤Id
     */
    private Long stepId;

    /**
     * 视频总时长
     */
    private  String  sumTime;

    /**
     * 视频播放时间
     */
    private  String videoTime;
    /**
     * 播放状态
     */
    private String isPlay;

    /**
     * 倍速 默认为一倍速度
     */
    private Double speed = 1d;


    @OnOpen
    public void onOpen(Session session, @PathParam("chapterId") Long chapterId, EndpointConfig config) {
        this.session = session;
        this.userId = (Long) config.getUserProperties().get("userId");

    }
    // 直接存入视频时长 TODO 前端配合重构代码  每0.5秒发一次请求  直接存入前端传来的数据
    @OnClose
    public void onClose() {
        synchronized (CourseExperimentVideoTimeWebsocket.class) {

            String begin = "";

            if (stepId != null) {
                begin = TimeHashMap.get(courseId, stepId) == null ? "" : TimeHashMap.get(courseId, stepId).toString();
            } else if(taskId != null ) {
                begin = TimeHashMap.get(courseId, taskId) == null ? "" : TimeHashMap.get(courseId, taskId).toString();
            }else if(chapterId != null){
                begin = TimeHashMap.get(courseId, chapterId) == null ? "" : TimeHashMap.get(courseId, chapterId).toString();
            }

            // experimentService.saveExperimentTime(chapterId, courseId, classId, userId,  videoTime, taskId, stepId, sumTime);

            if (!"".equals(begin)) {
                long timeStamp = System.currentTimeMillis();
                long sub = Math.abs(timeStamp- Long.valueOf(begin));
                BigDecimal intervalTime = BigDecimal.valueOf(NumberUtil.div(sub, 1000d, 2));
                intervalTime = NumberUtil.div(intervalTime, speed);
                Console.log(" -------时间差-------- "+ sub/1000);
                ExperimentVideoStatistics experimentVideoStatistics = experimentHelper.getByCondition(courseId, classId, chapterId, userId.intValue());
                if("1".equals(isPlay)){
                    // 查询表中对应的记录
                    if(ObjectUtil.isNotNull(experimentVideoStatistics) && ObjectUtil.isNotNull(experimentVideoStatistics.getVideoTime())){
                        intervalTime = NumberUtil.add(BigDecimal.valueOf(Double.valueOf(videoTime)), intervalTime);
                    }
                    int compare = -1;
                    if(experimentVideoStatistics != null && experimentVideoStatistics.getVideoSumTime() != null){
                         intervalTime.compareTo(BigDecimal.valueOf(Double.valueOf(experimentVideoStatistics.getVideoSumTime())));
                    }
                    if(compare == -1 || compare == 0){
                        experimentService.saveExperimentTime(chapterId, courseId, classId, userId,  intervalTime.toString(), taskId, stepId, sumTime);
                    }
                }else{
                        experimentService.saveExperimentTime(chapterId, courseId, classId, userId,  videoTime, taskId, stepId, sumTime);
                }
            }

        }
    }

    @OnMessage
    public void onMessage( String jsonStr, Session session) {
        // 暂时不需要实现该方法
        Gson gson=new Gson();
        ExperimentStatisticsParamOther experimentStatisticsParamOther =new ExperimentStatisticsParamOther();
        experimentStatisticsParamOther = gson.fromJson(jsonStr, ExperimentStatisticsParamOther.class);
        Boolean isHaveError = checkParam(experimentStatisticsParamOther);
        if(isHaveError){
            return;
        }
        this.courseId=experimentStatisticsParamOther.getCourseId();
        this.chapterId=experimentStatisticsParamOther.getChapterId();
        this.classId=experimentStatisticsParamOther.getClassId();
        this.stepId=experimentStatisticsParamOther.getStepId();
        this.taskId=experimentStatisticsParamOther.getTaskId();
        this.sumTime=experimentStatisticsParamOther.getSumTime();
        this.isPlay =experimentStatisticsParamOther.getIsPlay();
        this.videoTime = NumberUtil.roundStr(experimentStatisticsParamOther.getVideoTime(), 1, RoundingMode.DOWN);
        Console.log("++++++videoTime+++++" + videoTime);
        Console.log("++++++videoTime+++++" + videoTime);
        Console.log("++++++videoTime+++++" + videoTime);
        synchronized (CourseExperimentVideoTimeWebsocket.class) {
            try{
                if (stepId != null) {
                    TimeHashMap.put(courseId, stepId, System.currentTimeMillis());
                }else if(taskId != null){
                    TimeHashMap.put(courseId, taskId, System.currentTimeMillis());
                }else if(chapterId != null){
                    TimeHashMap.put(courseId, chapterId, System.currentTimeMillis());
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 检查参数是否正确
     * @param experimentStatisticsParamOther
     * @return
     */
    private Boolean checkParam(ExperimentStatisticsParamOther experimentStatisticsParamOther) {

        boolean isHaveError = StringUtils.isBlank(experimentStatisticsParamOther.getVideoTime());

        return isHaveError;
    }

    @OnError
    public void onError(Session session, Throwable error) {
        // 暂时不需要实现该方法
        error.printStackTrace();
    }

}
